﻿using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SObject.Test
{
    [TestFixture]
    class Object_Relation
    {
        [Test]
        [TestCase("ParentName", "ChildName", "ParentName:ChildName")]
        public void AddChild(string ParentName, string ChildName, string ChildCompleteName)
        {
            SObject.Object parent = new SObject.Object(ParentName);

            SObject.Object child = null;
            // an exception should be thrown when a child does not exist
            Assert.Throws<SObject.Exception>
                (
                    delegate
                    {
                        child = parent.GetChild(ChildName);
                    }
                );

            int childrenCount = parent.ChildrenCount;

            // an exception should be thrown when adding self as a child
            Assert.Throws<SObject.Exception>
                (
                    delegate
                    {
                        parent.AddChild(parent);
                    }
                );
            // make sure nothing had changed as well
            Assert.AreEqual(childrenCount, parent.ChildrenCount);
            Assert.AreEqual(null, parent.Parent);
            Assert.AreEqual("ParentName", parent.CompleteName);


            child = new SObject.Object(ChildName);
            parent.AddChild(child);
            // children count should have been incremented
            Assert.AreEqual(childrenCount + 1, parent.ChildrenCount);
            // the parent should has the child with the corresponding name
            Assert.AreEqual(true, parent.HasChild(ChildName));
            // get child should return the correct child
            SObject.Object returnedChild = parent.GetChild(ChildName);
            Assert.AreEqual(child, returnedChild);
            // the child's parent should be the corresponding object
            Assert.AreEqual(parent, child.Parent);
            // the child's root should be the parent's root
            Assert.AreEqual(parent.Root, child.Root);

            Assert.AreEqual(ChildCompleteName, child.CompleteName);

            // when the child is added again, an exception should be thrown
            Assert.Throws<SObject.Exception>
                (
                    delegate
                    {
                        parent.AddChild(child);
                    }
                );

            SObject.Object anotherChildWithSameName = new SObject.Object(ChildName);

            // when another child with the same name is added, an exception should be thrown
            Assert.Throws<SObject.Exception>
                (
                    delegate
                    {
                        parent.AddChild(anotherChildWithSameName);
                    }
                );
        }
    }
}
